package com.jdj.framework.dao.mybatis.dao;

import com.jdj.framework.core.base.vo.PageInfo;
import com.jdj.framework.dao.mybatis.entity.BaseEntity;
import com.jdj.framework.dao.mybatis.entity.condition.BaseEntityCondition;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Mybatis接口查询
 * @author caijinbang
 * @date 2019-04-14 11:43
 */
public interface MyBatisDao {
    /**
     * 根据condition查询记录总数
     *
     * @param condition 条件对象
     * @return 总数
     */
    <Condition extends BaseEntityCondition> int countByCondition(Condition condition);

    /**
     * 根据condition批量查询
     *
     * @param condition 条件对象
     * @return 实体集合
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> List<Entity> selectByCondition(
        Condition condition);

    /**
     * 根据condition批量查询（包含BLOB 数据）
     *
     * @param condition 条件对象
     * @return 实体集合
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> List<Entity> selectByConditionWithBLOBs(
        Condition condition);

    /**
     * 根据condition单个查询
     *
     * 没有结果集：返回null
     * 单个结果集：直接返回
     * 多个结果集：只取第一行
     *
     * @param condition 条件对象
     * @return 实体
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> Entity selectOneByCondition(Condition condition);

    /**
     * 根据condition单个查询（包含BLOB 数据）
     *
     * 没有结果集：返回null
     * 单个结果集：直接返回
     * 多个结果集：只取第一行
     *
     * @param condition 条件对象
     * @return 实体
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> Entity selectOneByConditionWithBLOBs(
        Condition condition);

    /**
     * 根据condition分页查询
     *
     * @param condition 条件对象
     * @return 分页对象
     */
    <Condition extends BaseEntityCondition> PageInfo selectPageByCondition(Condition condition);

    /**
     * 新增实体有值字段记录，返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int insert(Entity entity);

    /**
     * <pre>
     * 【推荐使用 insertList】
     * </pre>
     * 批量新增实体有值字段记录，返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    @Deprecated
    <Entity extends BaseEntity> int insert(List<Entity> entities);

    /**
     * 批量新增实体(如果主键为空，会提供一个32位字符)，返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int insertList(List<Entity> entities);

    /**
     * 新增实体有值字段记录，返回主键
     * @param entity
     * @return
     */
    <Entity extends BaseEntity, T> T insertWithPrimaryKey(Entity entity);

    /**
     * <pre>
     * 【推荐使用 insertListWithPrimaryKeys】
     * </pre>
     * 批量新增实体有值字段记录，返回主键集合
     * @param entities 实体集合
     * @return 主键集合
     */
    @Deprecated
    <Entity extends BaseEntity> List<Serializable> insertWithPrimaryKeys(List<Entity> entities);

    /**
     * 批量新增实体(如果主键为空，会提供一个32位字符)，返回主键集合
     *
     * @param entities 实体集合
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> insertListWithPrimaryKeys(List<Entity> entities);

    /**
     * 新增实体有值字段记录，返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity insertWithQuery(Entity entity);

    /**
     * 批量新增实体有值字段记录，返回实体集合
     *
     * @param entities 实体集合
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> insertWithQuery(List<Entity> entities);

    /**
     * 根据主键删除
     *
     * @param entityClass 实体类
     * @param primaryKeyValue 主键值
     * @return 影响行数
     */
    <Entity extends BaseEntity> int deleteByPrimaryKey(Class<Entity> entityClass, Serializable primaryKeyValue);

    /**
     * 删除实体（Id不能为空），返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int delete(Entity entity);

    /**
     * 根据条件删除实体，返回行数
     *
     * @param condition 条件对象
     * @return 影响行数
     */
    <Condition extends BaseEntityCondition> int deleteByCondition(Condition condition);

    /**
     * 批量删除实体，返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int delete(List<Entity> entities);

    /**
     * 更新实体有值字段记录，返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int update(Entity entity);

    /**
     * 更新实体（字段 = null 或 字段 = "" 的不更新），返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotEmpty(Entity entity);

    /**
     * 更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回行数
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotNull(Entity entity);

    /**
     * 根据条件更新实体有值字段记录，返回行数
     *
     * @param entity 实体
     * @param condition 条件对象
     * @return 影响行数
     */
    <Entity extends BaseEntity, Condition extends BaseEntityCondition> int updateByCondition(Entity entity,
        Condition condition);

    /**
     * 批量更新实体有值字段记录，返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int update(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 或 字段 = "" 的不更新），返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotEmpty(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回行数
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int updateNotNull(List<Entity> entities);

    /**
     * 更新实体有值字段记录，返回主键
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity, T> T updateWithPrimaryKey(Entity entity);

    /**
     * 更新实体（字段 = null 或 字段 = "" 的不更新），返回主键
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity, T> T updateNotEmptyWithPrimaryKey(Entity entity);

    /**
     * 更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回主键
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity, T> T updateNotNullWithPrimaryKey(Entity entity);

    /**
     * 批量更新实体有值字段记录，返回主键集合
     * @param entities 实体集合
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> updateWithPrimaryKeys(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 或 字段 = "" 的不更新），返回主键集合
     * @param entities 实体集合
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> updateNotEmptyWithPrimaryKeys(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回主键集合
     * @param entities 实体集合
     * @return 主键集合
     */
    <Entity extends BaseEntity> List<Serializable> updateNotNullWithPrimaryKeys(List<Entity> entities);

    /**
     * 更新实体有值字段记录，返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity updateWithQuery(Entity entity);

    /**
     * 更新实体（字段 = null 或 字段 = "" 的不更新），返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity updateNotEmptyWithQuery(Entity entity);

    /**
     * 更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回实体
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity updateNotNullWithQuery(Entity entity);

    /**
     * 批量更新实体有值字段记录，返回实体集合
     *
     * @param entities 实体集合
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> updateWithQuery(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 或 字段 = "" 的不更新），返回实体集合
     *
     * @param entities 实体集合
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> updateNotEmptyWithQuery(List<Entity> entities);

    /**
     * 批量更新实体（字段 = null 的不更新，字段 = "" 的会更新），返回实体集合
     *
     * @param entities 实体集合
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> updateNotNullWithQuery(List<Entity> entities);

    /**
     * 保存实体，返回影响行数
     *
     * 	1、优先判断设置 rowState，区分 增加，删除，修改；
     * 	2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entity 实体
     * @return 影响行数
     */
    <Entity extends BaseEntity> int save(Entity entity);

    /**
     * 批量保存实体，返回影响行数
     *
     * 	1、优先判断设置 rowState，区分 增加，删除，修改；
     * 	2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entities 实体集合
     * @return 影响行数
     */
    <Entity extends BaseEntity> int save(List<Entity> entities);

    /**
     * 保存实体，返回保存后的实体
     *
     * 	1、优先判断设置 rowState，区分 增加，删除，修改；
     * 	2、其次判断主键字段是否有值，区分 增加，修改；
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity saveWithQuery(Entity entity);

    /**
     * 批量保存实体，返回保存后的实体集合
     *
     * 	1、优先判断设置 rowState，区分 增加，删除，修改；
     * 	2、其次判断主键字段是否有值，区分 增加，修改；
     * @param entities 实体集合
     * @return 实体集合
     */
    <Entity extends BaseEntity> List<Entity> saveWithQuery(List<Entity> entities);

    /**
     * 根据主键查询
     *
     * @param entity 实体
     * @return 实体
     */
    <Entity extends BaseEntity> Entity selectByPrimaryKey(Entity entity);

    /**
     * 根据主键查询
     *
     * @param entityClass 实体类
     * @param primaryKeyValue 主键值
     * @return 实体
     */
    <Entity extends BaseEntity> Entity selectByPrimaryKey(Class<Entity> entityClass, Serializable primaryKeyValue);

    /**
     * 执行在mapper.xml里声明的sql，返回List集合数据
     *
     * @param statementId mapper.xml的声明Id
     *
     * @return
     */
    <E> List<E> selectListBySql(String statementId);

    /**
     * 执行在mapper.xml里声明的sql，返回List集合数据
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameterMap sql语句的参数
     *
     * @return
     */
    <E> List<E> selectListBySql(String statementId, Map<String, Object> parameterMap);

    /**
     *
     * 执行在mapper.xml里声明的sql，返回Map集合数据
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param mapKey 指定一个列名为Map数据的key
     *
     * @return
     */
    <K, V> Map<K, V> selectMapBySql(String statementId, String mapKey);

    /**
     *
     * 执行在mapper.xml里声明的sql，返回Map集合数据
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameterMap sql语句的参数
     *
     * @param mapKey 指定一个列名为Map数据的key
     *
     * @return
     */
    <K, V> Map<K, V> selectMapBySql(String statementId, Map<String, Object> parameterMap, String mapKey);

    /**
     * 执行在mapper.xml里声明的sql
     *
     * 没有结果集：返回null
     * 单个结果集：直接返回
     * 多个结果集：只取第一行
     *
     * @param statementId mapper.xml的声明Id
     *
     * @return
     */
    <T> T selectOneBySql(String statementId);

    /**
     * 执行在mapper.xml里声明的sql
     *
     * 没有结果集：返回null
     * 单个结果集：直接返回
     * 多个结果集：只取第一行
     *
     * @return
     */
    <T> T selectOneBySql(String statementId, Map<String, Object> parameterMap);

    /**
     * 执行在mapper.xml里声明的sql，返回影响行数
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameterMap sql语句的参数
     *
     * @return
     */
    int insertBySql(String statementId, Map<String, Object> parameterMap);

    /**
     * 执行在mapper.xml里声明的sql，返回影响行数
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameters 批量sql语句的参数
     *
     * @return
     */
    int insertBySql(String statementId, List<Map<String, Object>> parameters);

    /**
     * 执行在mapper.xml里声明的sql，返回影响行数
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameterMap sql语句的参数
     *
     * @return
     */
    int deleteBySql(String statementId, Map<String, Object> parameterMap);

    /**
     * 执行在mapper.xml里声明的sql，返回影响行数
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameters 批量sql语句的参数
     *
     * @return
     */
    int deleteBySql(String statementId, List<Map<String, Object>> parameters);

    /**
     * 执行在mapper.xml里声明的sql，返回影响行数
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameterMap sql语句的参数
     *
     * @return
     */
    int updateBySql(String statementId, Map<String, Object> parameterMap);

    /**
     * 执行在mapper.xml里声明的sql，返回影响行数
     *
     * @param statementId mapper.xml的声明Id
     *
     * @param parameters 批量sql语句的参数
     *
     * @return
     */
    int updateBySql(String statementId, List<Map<String, Object>> parameters);

    /**
     * 执行动态的insert sql，返回影响行数
     *
     * @param sql sql语句
     * 		例：insert into table_name
     * 				(field_name,field_name2)
     * 				values
     * 				(#{fieldName},#{fieldName2})
     *
     * @param parameterMap sql语句的参数
     * 		例：Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     *
     * @return
     */
    int insertByDynamicSql(String sql, Map<String, Object> parameterMap);

    /**
     * 执行动态的insert sql，返回影响行数
     *
     * @param sql sql语句
     * 		例：insert into table_name
     * 				(field_name,field_name2)
     * 				values
     * 				(#{fieldName},#{fieldName2})
     *
     * @param parameters 批量sql语句的参数
     * 		例：List<Map<String, Object>> parameters = new ArrayList<Map<String, Object>>();
     * 			Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     * 			parameters.add(parameterMap);
     *
     * @return
     */
    int insertByDynamicSql(String sql, List<Map<String, Object>> parameters);

    /**
     * 执行动态的delete sql，返回影响行数
     *
     * @param sql sql语句
     * 		例：delete from table_name
     * 			where
     * 				field_name = #{fieldName}
     * 				and
     * 				field_name2 = #{fieldName2}
     *
     * @param parameterMap sql语句的参数
     * 		例：Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     *
     * @return
     */
    int deleteByDynamicSql(String sql, Map<String, Object> parameterMap);

    /**
     * 执行动态的delete sql，返回影响行数
     *
     * @param sql sql语句
     * 		例：delete from table_name
     * 			where
     * 				field_name = #{fieldName}
     * 				and
     * 				field_name2 = #{fieldName2}
     *
     * @param parameters 批量sql语句的参数
     * 		例：List<Map<String, Object>> parameters = new ArrayList<Map<String, Object>>();
     * 			Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     * 			parameters.add(parameterMap);
     *
     * @return
     */
    int deleteByDynamicSql(String sql, List<Map<String, Object>> parameters);

    /**
     * 执行动态的update sql，返回影响行数
     *
     * @param sql sql语句
     * 		例：update table_name
     * 			set
     * 				field_name = #{fieldName}
     * 			where
     * 				field_name2 = #{fieldName2}
     *
     * @param parameterMap sql语句的参数
     * 		例：Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     *
     * @return
     */
    int updateByDynamicSql(String sql, Map<String, Object> parameterMap);

    /**
     * 执行动态的update sql，返回影响行数
     *
     * @param sql sql语句
     * 		例：update table_name
     * 			set
     * 				field_name = #{fieldName}
     * 			where
     * 				field_name2 = #{fieldName2}
     *
     * @param parameters 批量sql语句的参数
     * 		例：List<Map<String, Object>> parameters = new ArrayList<Map<String, Object>>();
     * 			Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     * 			parameters.add(parameterMap);
     *
     * @return
     */
    int updateByDynamicSql(String sql, List<Map<String, Object>> parameters);

    /**
     * 执行动态的select sql，返回Map数据
     *
     * 没有结果集：返回null
     * 单个结果集：直接返回
     * 多个结果集：只取第一行
     *
     * @param sql sql语句
     * 		例：select field_name,field_name2 from table_name
     *
     * @return
     */
    <K, V> Map<K, V> selectOneByDynamicSql(String sql);

    /**
     * 执行动态的select sql，返回Map数据
     *
     * 没有结果集：返回null
     * 单个结果集：直接返回
     * 多个结果集：只取第一行
     *
     * @param sql sql语句
     * 		例：select field_name,field_name2 from table_name
     * 			where field_name = #{fieldName}
     * 			and field_name2 = #{fieldName2}
     *
     * @param parameterMap  sql语句的参数
     * 		例：Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     *
     * @return
     */
    <K, V> Map<K, V> selectOneByDynamicSql(String sql, Map<String, Object> parameterMap);

    /**
     * 执行动态的select sql，返回List数据
     *
     * @param sql sql语句
     * 		例：select field_name,field_name2 from table_name
     *
     * @return
     */
    <K, V> List<Map<K, V>> selectListByDynamicSql(String sql);

    /**
     * 执行动态的select sql，返回List数据
     *
     * @param sql sql语句
     * 		例：select field_name,field_name2 from table_name
     * 			where field_name = #{fieldName}
     * 			and field_name2 = #{fieldName2}
     *
     * @param parameterMap sql语句的参数
     * 		例：Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     *
     * @return
     */
    <K, V> List<Map<K, V>> selectListByDynamicSql(String sql, Map<String, Object> parameterMap);

    /**
     * 执行动态的select sql，返回Map数据
     *
     * @param sql sql语句
     * 		例：select field_name,field_name2 from table_name
     *
     * @param mapKey 指定一个列名为Map数据的key
     *
     * @return
     */
    <K, V> Map<K, V> selectMapByDynamicSql(String sql, String mapKey);

    /**
     * 执行动态的select sql，返回Map数据
     *
     * @param sql sql语句
     * 		例：select field_name,field_name2 from table_name
     * 			where field_name = #{fieldName}
     * 			and field_name2 = #{fieldName2}
     *
     * @param parameterMap sql语句的参数
     * 		例：Map<String, Object> parameterMap = new HashMap<String, Object>();
     * 			parameterMap.put("fieldName","value");
     * 			parameterMap.put("fieldName2","value2");
     *
     * @param mapKey 指定一个列名为Map数据的key
     *
     * @return
     */
    <K, V> Map<K, V> selectMapByDynamicSql(String sql, Map<String, Object> parameterMap, String mapKey);

    /**
     *
     * 批量执行动态（增删改）sql，返回影响行数。
     * sqls（sql语句集合）与 parameters（sql语句的参数集合）的顺序必须一一对应
     *
     * @param sqls sql语句集合
     *
     * @param parameters sql语句的参数集合
     * @return
     */
    int executeSqls(List<String> sqls, List<Map<String, Object>> parameters);

}
